package ar.edu.itba.pod.legajo48062;

import ar.edu.itba.balance.api.AgentsBalancer;
import ar.edu.itba.balance.api.NodeAgent;
import ar.edu.itba.node.Node;
import ar.edu.itba.node.NodeInformation;
import ar.edu.itba.node.api.ClusterAdministration;
import ar.edu.itba.pod.agent.runner.Agent;
import ar.edu.itba.pod.multithread.EventDispatcher;
import ar.edu.itba.pod.multithread.LocalSimulation;
import ar.edu.itba.pod.time.TimeMapper;

public class DistributedSimulation extends LocalSimulation {
	private WrapperEventDispatcher localDispatcher;
	private DistributedAgentsBalancer agentsBalancer;
	private Cluster cluster;
	
	public DistributedSimulation(TimeMapper timeMapper, WrapperEventDispatcher localDispatcher, AgentsBalancer agentsBalancer, ClusterAdministration cluster) {
		super(timeMapper);
		this.localDispatcher=localDispatcher;
		this.agentsBalancer=(DistributedAgentsBalancer) agentsBalancer;
		this.cluster=(Cluster) cluster;
	}

	@Override
	public EventDispatcher dispatcher() {
		return localDispatcher;
	}
	
	@Override
	public void add(final Agent agent) {
		boolean success = false;
		
		while (!success){
			success = new Communication<AgentsBalancer>(cluster,Node.AGENTS_BALANCER){
				@Override
				public void remoteCall(AgentsBalancer stub, NodeInformation node) throws Exception {
					stub.addAgentToCluster(new NodeAgent(cluster.me(), agent));
				}
			}.unicast(agentsBalancer.getCoordinator(), true);
			if (!success){
				System.out.println("NO SE PUDO MANDAR EL UNICAST DE ADDAGENTTOCLUSTER AL COORDINADOR!!!");
			}
		}
	}
	
	public void addLocal(Agent agent) {
		super.add(agent);
	}
	
	public Cluster getCluster(){
		return cluster;
	}
	
}